/********************************************************************************
 ***                                                                          *** 
 ********************************************************************************
 *                                                                              * 
 *           Prject Name : MEMORIA                                              * 
 *                                                                              * 
 *             File Name : mainwindow.cpp                                       * 
 *                                                                              * 
 *            Programmer : LBW                                                  * 
 *                                                                              * 
 *            Start Date : 2020/12/26                                           * 
 *                                                                              * 
 *           Last Update : 2020/12/26  [LBW]                                    * 
 *                                                                              * 
 *------------------------------------------------------------------------------*
 * Functions:                                                                   * 
 *   MainWindow::MainWindow -- 主界面的构造函数                                 * 
 *   MainWindow::createActions -- 定义qt创建工具栏需要用到的Action              * 
 *   MainWindow::createToolBar -- 创建工具栏                                    * 
 *   MainWindow::createButtons -- 创建操作CardList的按钮                        * 
 *   MainWindow::newConnection -- 将按钮与CardList连接起来                      * 
 *   MainWindow::load -- 加载已有的卡片集                                       * 
 *   MainWindow::newCardList -- 创建新的卡片集                                  * 
 *   MainWindow::showCardList -- 显示已加载的卡片集                             * 
 *   MainWindow::lock -- 按键锁,限制用户操作                                    * 
 *   MainWindow::sliderValueChanged -- 拖动滚动条翻页                           * 
 *   MainWindow::nextButtonClicked -- 往后翻一页                                * 
 *   MainWindow::previousButtonClicked -- 往前翻一页                            * 
 *   MainWindow::cardSumChanged -- 卡片数量变化引起滚动条同步变化               * 
 *==============================================================================*/

#include <QtWidgets>
#include <QVector>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QVariant>
#include <QMessageBox>
#include <QPushButton>
#include <QFileInfo>

#include "parameter.h"
#include "mainwindow.h"
#include "cardlist.h"

/**********************************************************************************
 * MainWindow::MainWindow -- 主界面的构造函数                                     *
 *                                                                                *
 * INPUT: parent -- 指定MainWindow类的父对象                                      *
 *                                                                                *
 * OUTPUT: none                                                                   *
 *                                                                                *
 * WARNINGS: none                                                                 *
 *                                                                                *
 * HISTORY:                                                                       *
 *   2020/12/26 LBW : Created.                                                    *
 *================================================================================*/

MainWindow::MainWindow(QWidget *parent):QWidget(parent)
{
	resize(560,900);
	mainLayout = new QVBoxLayout;

	createActions();
	createToolBar();
	createButtons();

	mainLayout->addWidget(toolBar);
	mainLayout->addLayout(buttonLayout);
	mainLayout->setAlignment(Qt::AlignTop);
	setLayout(mainLayout);

	setFixedHeight(MAINWINDOWFIXEDHEIGHT);

	lock(INITMODE);
}

/**********************************************************************************
 * MainWindow::createActions -- 定义qt创建工具栏需要用到的Action                  *
 *                                                                                *
 * INPUT: none                                                                    *
 *                                                                                *
 * OUTPUT: none                                                                   *
 *                                                                                *
 * WARNINGS: none                                                                 *
 *                                                                                *
 * HISTORY:                                                                       *
 *   2020/12/26 LBW : Created.                                                    *
 *================================================================================*/

void MainWindow::createActions(){
	newAction = new QAction(tr("New"),this);
	connect(newAction,SIGNAL(triggered()),this,SLOT(newCardList()));

	loadAction = new QAction(tr("Load"),this);
	connect(loadAction,SIGNAL(triggered()),this,SLOT(load()));

	testAction = new QAction(tr("Test"),this);
	connect(testAction,SIGNAL(triggered()),this,SLOT(showCardList()));

	editAction = new QAction(tr("Edit"),this);
	connect(editAction,SIGNAL(triggered()),this,SLOT(showCardList()));

	insertAction = new QAction(tr("Insert"),this);

	deleteAction = new QAction(tr("Delete"),this);

	saveAction = new QAction(tr("Save"),this);
}

/**********************************************************************************
 * MainWindow::createToolBar -- 创建工具栏                                        *
 *                                                                                *
 * INPUT: none                                                                    *
 *                                                                                *
 * OUTPUT: none                                                                   *
 *                                                                                *
 * WARNINGS: none                                                                 *
 *                                                                                *
 * HISTORY:                                                                       *
 *   2020/12/26 LBW : Created.                                                    *
 *================================================================================*/

void MainWindow::createToolBar(){
	toolBar = new QToolBar(this);
	toolBar->addAction(newAction);
	toolBar->addAction(loadAction);
	toolBar->addAction(testAction);
	toolBar->addAction(editAction);
	toolBar->addAction(insertAction);
	toolBar->addAction(deleteAction);
	toolBar->addAction(saveAction);
}

/**********************************************************************************
 * MainWindow::createButtons -- 创建操作CardList的按钮                            *
 *                                                                                *
 * INPUT: none                                                                    *
 *                                                                                *
 * OUTPUT: none                                                                   *
 *                                                                                *
 * WARNINGS: none                                                                 *
 *                                                                                *
 * HISTORY:                                                                       *
 *   2020/12/26 LBW : Created.                                                    *
 *================================================================================*/

void MainWindow::createButtons(){
	previousPage = new QPushButton(this);
	previousPage->setText("Previous");
	previousPage->setFixedSize(previousPage->sizeHint());
	nextPage = new QPushButton(this);
	nextPage->setText("Next");
	nextPage->setFixedSize(nextPage->sizeHint());

	connect(previousPage,SIGNAL(clicked()),this,SLOT(previousButton_clicked()));
	connect(nextPage,SIGNAL(clicked()),this,SLOT(nextButton_clicked()));

	slider = new QSlider(Qt::Horizontal,this);
	slider->setFixedWidth(SLIDERFIXEDWIDTH);
	slider->setTracking(true);
	connect(slider,SIGNAL(valueChanged(int)),this,SLOT(sliderValueChanged(int)));

	pageLabel = new QLabel(this);
	pageLabel->setFixedWidth(PAGELABELFIXEDWIDTH);
	pageLabel->setText("P0/0");

	buttonLayout = new QHBoxLayout;
	buttonLayout->setAlignment(Qt::AlignBottom | Qt::AlignLeft);
	buttonLayout->addWidget(previousPage);
	buttonLayout->addWidget(nextPage);
	buttonLayout->addWidget(slider);
	buttonLayout->addWidget(pageLabel);
}

/**********************************************************************************
 * MainWindow::newConnection -- 将按钮与CardList连接起来                          *
 *                                                                                *
 * INPUT: none                                                                    *
 *                                                                                *
 * OUTPUT: none                                                                   *
 *                                                                                *
 * WARNINGS: none                                                                 *
 *                                                                                *
 * HISTORY:                                                                       *
 *   2020/12/26 LBW : Created.                                                    *
 *================================================================================*/

void MainWindow::newConnection(){
	connect(slider,SIGNAL(valueChanged(int)),cardList,SLOT(sliderValueChanged(int)));
	connect(testAction,SIGNAL(triggered()),cardList,SLOT(testButton_clicked()));
	connect(editAction,SIGNAL(triggered()),cardList,SLOT(editButton_clicked()));
	connect(insertAction,SIGNAL(triggered()),cardList,SLOT(insertButton_clicked()));
	connect(deleteAction,SIGNAL(triggered()),cardList,SLOT(deleteButton_clicked()));
	connect(saveAction,SIGNAL(triggered()),cardList,SLOT(saveButton_clicked()));
	connect(cardList,SIGNAL(lockPlease(int)),this,SLOT(lock(int)));
	connect(cardList,SIGNAL(cardSumChanged(int,int)),this,SLOT(cardSumChanged(int,int)));
}

/**********************************************************************************
 * MainWindow::newCardList -- 创建新的卡片集                                      *
 *                                                                                *
 * INPUT: none                                                                    *
 *                                                                                *
 * OUTPUT: none                                                                   *
 *                                                                                *
 * WARNINGS: none                                                                 *
 *                                                                                *
 * HISTORY:                                                                       *
 *   2020/12/26 LBW : Created.                                                    *
 *================================================================================*/

void MainWindow::newCardList(){
	bool ok;
	QString text = QInputDialog::getText(this,"Dialog","Input the new file's name",QLineEdit::Normal,"new",&ok);	
	QFileInfo fileInfo("../user/" + text + ".db");
	if(ok && !text.isEmpty() && !fileInfo.isFile()){	
		//删掉旧的卡片集		
		if(cardList != nullptr){
			disconnect(slider,0,cardList,0);
			mainLayout->removeWidget(cardList);	
			cardList->deleteLater();
		}
		//创建新的卡片集
		cardList = new CardList(text,this);
		//主窗口按钮连接新卡片集的槽
		newConnection();
		//锁按键
		lock(LOADMODE);
		//设置滑动条
		cardSumChanged(0,0);

		return;
	}else{
		qDebug()<<"db exist!!";
	}
}

/**********************************************************************************
 * MainWindow::load -- 加载已有的卡片集                                           *
 *                                                                                *
 * INPUT: none                                                                    *
 *                                                                                *
 * OUTPUT: none                                                                   *
 *                                                                                *
 * WARNINGS: none                                                                 *
 *                                                                                *
 * HISTORY:                                                                       *
 *   2020/12/26 LBW : Created.                                                    *
 *================================================================================*/

void MainWindow::load(){
	QFileDialog fileDialog;
	fileDialog.setAcceptMode(QFileDialog::AcceptOpen);
	fileDialog.setOption(QFileDialog::DontUseNativeDialog);
	fileDialog.setDirectory("../user");
	if(fileDialog.exec() == QDialog::Accepted){
		QString filePath = fileDialog.selectedFiles().at(0);
		QFileInfo *fileInfo = new QFileInfo(filePath);

		//删掉旧的卡片集		
		if(cardList != nullptr){

			//!!!不加这句在delete前还会触发sliderValueChanged槽导致崩溃
			disconnect(slider,0,cardList,0);
			
			mainLayout->removeWidget(cardList);	
			cardList->deleteLater();
		}

		//创建新的卡片集
		cardList = new CardList(fileInfo->baseName(),this);

		//主窗口按钮连接新卡片集的槽
		newConnection();

		//锁按键
		lock(LOADMODE);

		//设置滑动条
		cardSumChanged(cardList->getCardSum(),0);
	}	
	return;
}

/**********************************************************************************
 * MainWindow::showCardList -- 显示已加载的卡片集                                 *
 *                                                                                *
 * INPUT: none                                                                    *
 *                                                                                *
 * OUTPUT: none                                                                   *
 *                                                                                *
 * WARNINGS: none                                                                 *
 *                                                                                *
 * HISTORY:                                                                       *
 *   2020/12/26 LBW : Created.                                                    *
 *================================================================================*/

void MainWindow::showCardList(){
	if(buttonLayout != nullptr){
		mainLayout->removeItem(buttonLayout);
	}
	previousPage->setEnabled(true);
	nextPage->setEnabled(true);
	slider->setEnabled(true);
	pageLabel->setEnabled(true);
	mainLayout->addLayout(buttonLayout);
	mainLayout->addWidget(cardList);
	
}

/**********************************************************************************
 * MainWindow::lock -- 按键锁,限制用户操作                                        *
 *                                                                                *
 * INPUT: runMode -- 程序当前的运行状态                                           *
 *                                                                                *
 * OUTPUT: none                                                                   *
 *                                                                                *
 * WARNINGS: none                                                                 *
 *                                                                                *
 * HISTORY:                                                                       *
 *   2020/12/26 LBW : Created.                                                    *
 *================================================================================*/

void MainWindow::lock(int runMode){
	qDebug() <<"lock!runMode = "<<runMode;
	if(runMode == INITMODE){
		testAction->setEnabled(false);
		editAction->setEnabled(false);
		insertAction->setEnabled(false);
		deleteAction->setEnabled(false);
		saveAction->setEnabled(false);
		previousPage->setEnabled(false);
		nextPage->setEnabled(false);
		slider->setEnabled(false);
	}else if(runMode == TESTMODE){
		testAction->setEnabled(false);
		editAction->setEnabled(true);
		insertAction->setEnabled(false);
		deleteAction->setEnabled(false);
		saveAction->setEnabled(false);
		previousPage->setEnabled(true);
		nextPage->setEnabled(true);
		slider->setEnabled(true);
	}else if(runMode == EDITMODE){
		testAction->setEnabled(false);
		editAction->setEnabled(false);
		insertAction->setEnabled(true);
		deleteAction->setEnabled(true);
		saveAction->setEnabled(true);		
		previousPage->setEnabled(true);
		nextPage->setEnabled(true);
		slider->setEnabled(true);
	}else if(runMode == SAVEMODE){
		testAction->setEnabled(true);
		editAction->setEnabled(false);
		insertAction->setEnabled(true);
		deleteAction->setEnabled(true);
		saveAction->setEnabled(true);		
		previousPage->setEnabled(true);
		nextPage->setEnabled(true);
		slider->setEnabled(true);
	}else if(runMode == LOADMODE){
		editAction->setEnabled(true);
		testAction->setEnabled(true);
		insertAction->setEnabled(false);
		deleteAction->setEnabled(false);
		saveAction->setEnabled(false);
		previousPage->setEnabled(false);
		nextPage->setEnabled(false);
		slider->setEnabled(false);
	}
}

/**********************************************************************************
 * MainWindow::nextButtonClicked -- 往后翻一页                                    *
 *                                                                                *
 * INPUT: none                                                                    *
 *                                                                                *
 * OUTPUT: none                                                                   *
 *                                                                                *
 * WARNINGS: none                                                                 *
 *                                                                                *
 * HISTORY:                                                                       *
 *   2020/12/26 LBW : Created.                                                    *
 *================================================================================*/

void MainWindow::nextButton_clicked(){
	slider->setValue(slider->value() + 1);	
	slider->setSliderPosition(slider->value());
}

/**********************************************************************************
 * MainWindow::previousButtonClicked -- 往前翻一页                                *
 *                                                                                *
 * INPUT: none                                                                    *
 *                                                                                *
 * OUTPUT: none                                                                   *
 *                                                                                *
 * WARNINGS: none                                                                 *
 *                                                                                *
 * HISTORY:                                                                       *
 *   2020/12/26 LBW : Created.                                                    *
 *================================================================================*/

void MainWindow::previousButton_clicked(){
	slider->setValue(slider->value() - 1);	
	slider->setSliderPosition(slider->value());
}

/**********************************************************************************
 * MainWindow::cardSumChanged -- 卡片数量变化引起滚动条同步变化                   *
 *                                                                                *
 *   根据cardSum参数来设定slider的最大值                                          *
 *   根据thisPageBegin参数来设定slider的当前值                                    *
 *                                                                                *
 * INPUT: cardSum -- 卡片总数                                                     *
 *        thisPageBegin -- 当前页显示的是第几张卡片                               *
 *                                                                                *
 * OUTPUT: none                                                                   *
 *                                                                                *
 * WARNINGS: none                                                                 *
 *                                                                                *
 * HISTORY:                                                                       *
 *   2020/12/26 LBW : Created.                                                    *
 *================================================================================*/

void MainWindow::cardSumChanged(int cardSum,int thisPageBegin){
	page = cardSum/CARDSPERPAGE;
	thisPage = thisPageBegin/CARDSPERPAGE;
	if(cardSum == 0){
		pageLabel->setText("P0/0");
		slider->setValue(0);
		slider->setMaximum(0);
		return;
	}
	
	if(cardSum%CARDSPERPAGE == 0){
		page = page - 1; 
		pageLabel->setText("P" + QString::number(thisPage) + "/" + QString::number(page));
		slider->setMaximum(page);
	}else{
		pageLabel->setText("P" + QString::number(thisPage) + "/" + QString::number(page));
		slider->setMaximum(page);
	}

	slider->setValue(thisPage);

	return;
}

/**********************************************************************************
 * MainWindow::sliderValueChanged -- 拖动滚动条翻页                               *
 *                                                                                *
 *   slider的值发生变化的时候要更新显示                                           *
 *                                                                                *
 * INPUT: value -- slider当前的值,代表现在处于卡片集的第几页                      *
 *                                                                                *
 * OUTPUT: none                                                                   *
 *                                                                                *
 * WARNINGS: none                                                                 *
 *                                                                                *
 * HISTORY:                                                                       *
 *   2020/12/26 LBW : Created.                                                    *
 *================================================================================*/

void MainWindow::sliderValueChanged(int value){
	pageLabel->setText("P" + QString::number(value) + "/" + QString::number(page));
}









